#include <iostream>
#include <cmath>
#include <stdlib.h>
#include <time.h>
#include "main.h"


#include "WorldStatusUpdate.pb.h"
#include "Commands.pb.h"
#include "ProtobufUtil.hh"

using namespace strategy_protocol;
using namespace protoutil;
using namespace std;

void TheStrategy::mymap_building()
{
        int prev_x=translation_x;
        int prev_y=translation_y;
        vector<vector<char> > prev_mymap;
        prev_mymap.resize(M);
        for(int i=0;i<M;i++)
			prev_mymap[i].resize(N);
        for(unsigned int i=0;i<mymap.size();i++)
            for(unsigned int j=0;j<mymap[i].size();j++)
                prev_mymap[i][j]=mymap[i][j];
        vector<vector<char> > prev_undiscovered;
        prev_undiscovered.resize(M);
        for(int i=0;i<M;i++)
			prev_undiscovered[i].resize(N);
        for(unsigned int i=0;i<discovered.size();i++)
            for(unsigned int j=0;j<discovered[i].size();j++)
                prev_undiscovered[i][j]=discovered[i][j];
		Position tmp;
		for(int i=0;i<world.bases_size();i++)
		{
			tmp = world.bases(i).common().position();
			max_x = max(max_x,tmp.x());
			max_y = max(max_y,tmp.y());
            min_x = min(tmp.x(),min_x);
            min_y = min(tmp.y(),min_y);
		}
		for(int i=0;i<world.obstacles_size();i++)
		{
			tmp = world.obstacles(i).common().position();
			max_x = max(max_x,tmp.x());
			max_y = max(max_y,tmp.y());
            min_x = min(tmp.x(),min_x);
            min_y = min(tmp.y(),min_y);
		}
		for(int i=0;i<world.mines_size();i++)
		{
			tmp = world.mines(i).common().position();
			max_x = max(max_x,tmp.x());
			max_y = max(max_y,tmp.y());
            min_x = min(tmp.x(),min_x);
            min_y = min(tmp.y(),min_y);
		}
		for(int i=0;i<world.workers_size();i++)
		{
			tmp = world.workers(i).common().position();
			max_x = max(max_x,tmp.x());
			max_y = max(max_y,tmp.y());
            min_x = min(tmp.x(),min_x);
            min_y = min(tmp.y(),min_y);
		}
		for(int i=0;i<world.soldiers_size();i++)
		{
			tmp = world.soldiers(i).common().position();
			max_x = max(max_x,tmp.x());
			max_y = max(max_y,tmp.y());
            min_x = min(tmp.x(),min_x);
            min_y = min(tmp.y(),min_y);
		}
//		for(int i=0;i<world.bosses_size();i++)
//		{
//			tmp = world.bosses(i).common().position();
//			max_x = max(max_x,tmp.x());
//			max_y = max(max_y,tmp.y());
//            min_x = min(tmp.x(),min_x);
//            min_y = min(tmp.y(),min_y);
//		}
//		for(int i=0;i<world.minions_size();i++)
//		{
//			tmp = world.minions(i).common().position();
//			max_x = max(max_x,tmp.x());
//			max_y = max(max_y,tmp.y());
//            min_x = min(tmp.x(),min_x);
//            min_y = min(tmp.y(),min_y);
//		}
		M=max_x-min_x+20 ;//a legnagyobb látótávolságot hozzáadva
		N=max_y-min_y+20; //a legnagyobb látótávolságot hozzáadva
        translation_x=min_x-10;
        translation_y=min_y-10;
		cerr << translation_x<<" "<< translation_y<<" "<< prev_x<<" "<< prev_y<<" "<<M << " " <<N <<endl;
        mymap.clear();
        mymap.resize(M);
        for(int i=0;i<M;i++)
			mymap[i].resize(N,' ');

        discovered.clear();
        discovered.resize(M);
        for(int i=0;i<M;i++)
			discovered[i].resize(N,false);
		////megtartjuk az allando dolgokat, kitoroljuk a valtozokat
        for(unsigned int i=0;i<prev_mymap.size();i++)
            for(unsigned int j=0;j<prev_mymap[i].size();j++)
                if(prev_mymap[i][j]=='-' || prev_mymap[i][j]=='S' || prev_mymap[i][j]=='s' || prev_mymap[i][j]=='W'     || prev_mymap[i][j]=='w' || prev_mymap[i][j]=='.')
                    prev_mymap[i][j]=' ';
        for(unsigned int i=0;i<prev_mymap.size();i++)
            for(unsigned int j=0;j<prev_mymap[i].size();j++)
                mymap[i+prev_x-translation_x][j+prev_y-translation_y]=prev_mymap[i][j];
		for(unsigned int i=0;i<prev_undiscovered.size();i++)
            for(unsigned int j=0;j<prev_undiscovered[i].size();j++)
                discovered[i+prev_x-translation_x][j+prev_y-translation_y]=prev_undiscovered[i][j];
		for(int i=0;i<world.bases_size();i++)
		{
   			if(world.bases(i).team()==MYTEAM)
            {
                tmp = world.bases(i).common().position();
                mymap[tmp.x()-translation_x][tmp.y()-translation_y]='B';
                cerr << "Base (" << tmp.x()-translation_x << ", " << tmp.y()-translation_y << ") health: " <<
                    world.bases(i).health() << endl;
                for(int x=-6;x<=6;x++)
                    for(int y=-6;y<=6;y++)
                        if(0<=tmp.x()-translation_x+x && tmp.x()-translation_x+x<M && 0<=tmp.y()-translation_y+y && tmp.y()-translation_y+y<N) discovered[tmp.x()-translation_x+x][tmp.y()-translation_y+y]=true;
            }
            else
            {
                tmp = world.bases(i).common().position();
                mymap[tmp.x()-translation_x][tmp.y()-translation_y]='B';
                cerr << "OpponentBase (" << tmp.x()-translation_x << ", " << tmp.y()-translation_y << ") health: " <<
                    world.bases(i).health() << endl;
            }
		}
//		for(int i=0;i<world.bosses_size();i++)
//		{
//			tmp = world.bosses(i).common().position();
//			mymap[tmp.x()-translation_x][tmp.y()-translation_y]='b';
//			cerr << "Boss (" << tmp.x()-translation_x << ", " << tmp.y()-translation_y << ") health: " <<
//				world.bosses(i).health() << endl;
//		}
//        if(boss_found && !invasion)
//		{
//			for(int i=-boss_shoot_dist;i<=boss_shoot_dist;i++)
//					for(int j=-boss_shoot_dist;j<=boss_shoot_dist;j++)
//						if(0<=boss_pos.x()-translation_x+i && boss_pos.x()-translation_x+i<M && 0<=boss_pos.y()-translation_y+j && boss_pos.y()-translation_y+j<N)
//							mymap[boss_pos.x()-translation_x+i][boss_pos.y()-translation_y+j]='.';
//						mymap[boss_pos.x()-translation_x][boss_pos.y()-translation_y]='b';
//		}
		for(int i=0;i<world.obstacles_size();i++)
		{
			tmp = world.obstacles(i).common().position();
			mymap[tmp.x()-translation_x][tmp.y()-translation_y]='X';
		}
		for(int i=0;i<world.mines_size();i++)
		{
			bool found = false;
			for(unsigned int j=0;j<mines.size() && !found;++j)
				if(mines[j].common().id() == world.mines(i).common().id())
					found = true;
			if(!found)
				mines.push_back(world.mines(i));

			tmp = world.mines(i).common().position();
			mymap[tmp.x()-translation_x][tmp.y()-translation_y]='M';
			cerr << "Mine (" << tmp.x()-translation_x << ", " << tmp.y()-translation_y << ") capacity: " <<
				world.mines(i).capacity() << endl;
		}
		for(int i=0;i<world.workers_size();i++)
		{
			tmp = world.workers(i).common().position();
			if(world.workers(i).team()==MYTEAM)
            {
                mymap[tmp.x()-translation_x][tmp.y()-translation_y]='W';
                cerr << "Worker (" << tmp.x()-translation_x << ", " << tmp.y()-translation_y << ") resource: " <<
                    world.workers(i).resource() << ", health: " <<  world.workers(i).health() << endl;
                for(int x=-5;x<=5;x++)
                    for(int y=-5;y<=5;y++)
                        if(0<=tmp.x()-translation_x+x && tmp.x()-translation_x+x<M && 0<=tmp.y()-translation_y+y && tmp.y()-translation_y+y<N) discovered[tmp.x()-translation_x+x][tmp.y()-translation_y+y]=true;
            }
            else
            {
                mymap[tmp.x()-translation_x][tmp.y()-translation_y]='w';
                cerr << "Opponent Worker (" << tmp.x()-translation_x << ", " << tmp.y()-translation_y << ") resource: " <<
                    world.workers(i).resource() << ", health: " <<  world.workers(i).health() << endl;
            }

		}
		for(int i=0;i<world.soldiers_size();i++)
		{
            if(world.soldiers(i).team()==MYTEAM)
            {
                tmp = world.soldiers(i).common().position();
                mymap[tmp.x()-translation_x][tmp.y()-translation_y]='S';
                cerr << "Soldier (" << tmp.x()-translation_x << ", " << tmp.y()-translation_y << ") health: " <<
                    world.soldiers(i).health() << endl;
                for(int x=-5;x<=5;x++)
                    for(int y=-5;y<=5;y++)
                        if(0<=tmp.x()-translation_x+x && tmp.x()-translation_x+x<M && 0<=tmp.y()-translation_y+y && tmp.y()-translation_y+y<N) discovered[tmp.x()-translation_x+x][tmp.y()-translation_y+y]=true;
            }
            else
            {
                tmp = world.soldiers(i).common().position();
                mymap[tmp.x()-translation_x][tmp.y()-translation_y]='s';
                cerr << "Opponent Soldier (" << tmp.x()-translation_x << ", " << tmp.y()-translation_y << ") health: " <<
                    world.soldiers(i).health() << endl;
            }
		}
		// if(boss_found && invasion)
		// {
			// for(int i=-soldier_shoot_dist;i<=soldier_shoot_dist;i++)
					// for(int j=-soldier_shoot_dist;j<=soldier_shoot_dist;j++)
						// if(0<=boss_pos.x()-translation_x+i && boss_pos.x()-translation_x+i<M && 0<=boss_pos.y()-translation_y+j && boss_pos.y()-translation_y+j<N)
							// mymap[boss_pos.x()-translation_x+i][boss_pos.y()-translation_y+j]='.';
						// mymap[boss_pos.x()-translation_x][boss_pos.y()-translation_y]='b';
		// }

//		for(int i=0;i<world.minions_size();i++)
//		{
//			tmp = world.minions(i).common().position();
//			mymap[tmp.x()-translation_x][tmp.y()-translation_y]='m';
//		}

		computing_all_reachable_positions_from_base();
		for(unsigned int i=0;i<mymap.size();i++)
			for(unsigned int j=0;j<mymap[i].size();j++)
				if(!reachable_pos[i][j] && mymap[i][j]==' ') mymap[i][j]='-';
		cerr<<"map M = "<<M<<endl;
		cerr<<"map N = "<<N<<endl;
		cerr << "</log>\n";
		cerr << "<map>\n";
		cerr << "Resources: " << world.resource() << endl;
		for(unsigned int i=0;i<mymap.size();i++)
		{
			for(unsigned int j=0;j<mymap[i].size();j++)
				cerr<<mymap[i][j];
			cerr<<endl;
		}
		cerr << "</map>\n";
		cerr << "<log>\n";
}
